package com.eliza.music.model.db

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteOpenHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.work.Clock
import com.eliza.music.model.constant.Music_DATABASE_NAME
import com.eliza.music.model.dao.SongDao
import com.eliza.music.model.entity.Playlist
import com.eliza.music.model.entity.Song
import java.util.concurrent.Executor


@Database(
    entities = [Song::class, Playlist::class],
    version = 1,
    exportSchema = false,
)
abstract class MusicDatabase : RoomDatabase() {
    abstract fun songDao(): SongDao

    companion object {
        /**
         * Creates an instance of the MusicDatabase.
         *
         * @param context         A context (this method will use the application context from it)
         * @param queryExecutor   An [Executor] that will be used to execute all async Room
         * queries.
         * @param clock           The [Clock] to use for pruning operations
         * @param useTestDatabase `true` to generate an in-memory database that allows main thread
         * access
         * @return The created MusicDatabase
         */
        @JvmStatic
        fun create(
            context: Context,
            queryExecutor: Executor,
            useTestDatabase: Boolean
        ): MusicDatabase {
            val builder = if (useTestDatabase) {
                Room.inMemoryDatabaseBuilder(context, MusicDatabase::class.java)
                    .allowMainThreadQueries()
            } else {
                Room.databaseBuilder(context, MusicDatabase::class.java, Music_DATABASE_NAME)
                    .openHelperFactory { configuration ->
                        val configBuilder = SupportSQLiteOpenHelper.Configuration.builder(context)
                        configBuilder.name(configuration.name)
                            .callback(configuration.callback)
                            .noBackupDirectory(true)
                            .allowDataLossOnRecovery(true)
                        FrameworkSQLiteOpenHelperFactory().create(configBuilder.build())
                    }
            }
            return builder.setQueryExecutor(queryExecutor)
                .fallbackToDestructiveMigration()
                .build()
        }
    }
}

